package handlers

import (
	"InstantImage/config"
	"InstantImage/tcpService"
	"InstantImage/util"
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/jpeg"
	"image/png"
	"io"
	"math"
	"mime/multipart"
	"net/http"
	"sync"

	"github.com/gin-gonic/gin"
	"github.com/nfnt/resize"
	"golang.org/x/image/bmp"
)

func getUploadHandler(service *tcpService.TcpService) gin.HandlerFunc {
	return func(c *gin.Context) {
		form, err := c.MultipartForm()
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		var keys []string
		var mu sync.Mutex
		var wg sync.WaitGroup
		files := form.File["image"]

		for _, file := range files {
			wg.Add(1)
			go func(file *multipart.FileHeader) {
				dialSET, _ := service.SetPool.Get()
				defer service.SetPool.Put(dialSET)
				defer wg.Done()
				src, _ := file.Open()
				defer src.Close()
				data, _ := io.ReadAll(src)
				data, err = compressImage(data)
				if err != nil {
					panic(err)
				}
				key := util.MD5(data)
				base64Data := base64.StdEncoding.EncodeToString(data)
				_, err := util.Set(dialSET, []byte(key), []byte(base64Data))
				if err != nil {
					c.JSON(http.StatusNotFound, gin.H{
						"message": "SetFailed",
					})
				}
				mu.Lock()
				keys = append(keys, fmt.Sprintf("http://%s:%s/image/%s", config.CurIp, config.CurPort, key))
				mu.Unlock()
			}(file)
		}
		wg.Wait()
		c.JSON(http.StatusOK, gin.H{"message": "ok", "keys": keys})
	}
}

func compressImage(b []byte) ([]byte, error) {
	// 解码图片
	img, format, err := image.Decode(bytes.NewReader(b))
	if err != nil {
		return b, nil
	}
	// fmt.Println(format)
	// 创建一个缓冲区用于保存压缩后的图片
	buf := new(bytes.Buffer)

	// 调整图片大小（例如缩放为原来的 50%）
	newWidth := uint(math.Round(float64(img.Bounds().Max.X) * 0.5))
	newHeight := uint(math.Round(float64(img.Bounds().Max.Y) * 0.5))

	// 使用 resize 库进行缩放
	resizedImg := resize.Resize(newWidth, newHeight, img, resize.Lanczos3)

	// 根据原始图片格式进行编码
	switch format {
	case "jpeg":
		err = jpeg.Encode(buf, resizedImg, &jpeg.Options{Quality: 80})
	case "png":
		err = png.Encode(buf, resizedImg)
	case "bmp":
		err = bmp.Encode(buf, resizedImg)
	default:
		buf = bytes.NewBuffer(b)
		err = nil
	}

	if err != nil {
		return nil, fmt.Errorf("failed to encode image: %v", err)
	}

	// 返回压缩后的图片数据
	return buf.Bytes(), nil
}
